#include <iostream>
#include <string>
#include <unistd.h>
#include <vector>
#include <cstdlib>
#include <sys/types.h>
#include <functional>
#include <sys/wait.h>
#include "Task.hpp"
#include"Channel.hpp"
using namespace std;

using work_t = std::function<void()>;
enum
{
    OK = 0,
    UsageError,
    PipeError,
    ForkError
};

void Usage(string proc)
{
    cout << "Usage" << proc << "process->null" << endl;
}
void Worker()
{
    while (true)
    {
        int cmd = 0;
        int n = ::read(0, &cmd, sizeof(cmd));
        if (n == sizeof(cmd))
        {
            tm.Excute(cmd);
        }
        else if (n == 0)
        {
            cout << "pid: " << getpid() << "quit..." << endl;
            break;
        }
        else
        {
        }
    }
}
// void Print()
// {
// }
// void Download()
// {
// }
int InitProcessPoll(std::vector<Channel> &channels, int num, work_t work)
{
    for (int i = 0; i < num; i++)
    {
        int pipefd[2] = {0};
        int n = pipe(pipefd);
        if (n < 0)
            return PipeError;

        pid_t id = fork();
        if (id < 0)
            return ForkError;
        if (id == 0)
        {
            for(auto &c : channels)
            c.Close();
            ::close(pipefd[1]);
            dup2(pipefd[0], 0);
            
            work();
            ::exit(0);
        }

        // 父进程执行
        ::close(pipefd[0]);
        channels.emplace_back(pipefd[1], id);
    }
    return OK;
}
void DispatchTask(std::vector<Channel> &channels)
{
    int who = 0;
    int num = 20;
    while (num--)
    {
        // a,旋转一个子任务
        int task = tm.SleltTask();
        // b，选择一个子进程
        Channel &curr = channels[who++];
        who %= channels.size();
        cout << "####################################" << endl;
        cout << "send " << task << "to" << curr.Name() << "任务还剩" << num << endl;
        cout << "####################################" << endl;

        // c，派发任务
        curr.Send(task);
        // sleep(1);
    }
}
void CleanProcessPool(std::vector<Channel> &channels)
{
    for (auto &c : channels)
    {
        c.Close();
    }
    for (auto &c : channels)
    {
        pid_t rid = waitpid(c.Id(), nullptr, 0);
        if (rid > 0)
        {
            cout << "child" << rid << "wait ....success " << endl;
        }
    }
}
void DebugPrint(std::vector<Channel> &channels)
{
    for (auto &c : channels)
    {
        cout << c.Name() << endl;
    }
}
